package com.leon.alishop.core.bof.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.leon.alishop.core.bo.CityAreaBo;
import com.leon.alishop.core.bof.CityAreaBof;
import com.leon.alishop.core.cache.CacheManage;
import com.leon.alishop.core.cache.CacheTypeEnum;
import com.leon.alishop.core.service.CityAreaService;
import com.leon.alishop.model.CityArea;

@Service("cityAreaBof")
public class CityAreaBofImpl implements CityAreaBof {

	private static final String CITY_AREA_LIST_KEY = "city_area_bo_map_key";

	@Override
	public List<CityAreaBo> findAllCityArea() {
		Map<Integer, CityAreaBo> cityAreaBoMap = getCityAreaBoMapWithCache();
		if(cityAreaBoMap==null || cityAreaBoMap.size()==0)
			return null;
		return new ArrayList<CityAreaBo>(cityAreaBoMap.values());
	}

	@Override
	public List<CityAreaBo> findAllCityAreaTree() {
		Map<Integer, CityAreaBo> cityAreaBoMap = getCityAreaBoMapWithCache();
		List<CityAreaBo> ret = new ArrayList<CityAreaBo>();
		for (CityAreaBo bo : cityAreaBoMap.values()) {
			if (bo.getLevel() != null && bo.getLevel().intValue() == 1)
				ret.add(bo);
		}
		return ret;
	}

	@Override
	public CityAreaBo findCityAreaTreeById(Integer cityAreaId) {
		Map<Integer, CityAreaBo> cityAreaBoMap = getCityAreaBoMapWithCache();
		CityAreaBo bo;
		int i = 0;
		while ((bo = cityAreaBoMap.get(cityAreaId)) != null
				&& bo.getLevel() != null && bo.getLevel().intValue() != 1
				&& i++ < 5) {
			cityAreaId = bo.getParentId();
		}
		return bo;
	}

	@Override
	public CityAreaBo findCityAreaById(Integer cityAreaId) {
		if (cityAreaId == null)
			return null;
		Map<Integer, CityAreaBo> cityAreaBoMap = getCityAreaBoMapWithCache();
		return cityAreaBoMap.get(cityAreaId);
	}

	@Override
	public CityAreaBo findCityAreaByName(String name) {
		if (StringUtils.isBlank(name))
			return null;
		Map<Integer, CityAreaBo> cityAreaBoMap = getCityAreaBoMapWithCache();
		for (CityAreaBo bo : cityAreaBoMap.values()) {
			if (bo.getName().equalsIgnoreCase(name))
				return bo;
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	private Map<Integer, CityAreaBo> getCityAreaBoMapWithCache() {
		Map<Integer, CityAreaBo> cityAreaBoMap = (Map<Integer, CityAreaBo>) CacheManage
				.get(CITY_AREA_LIST_KEY, CacheTypeEnum.CITY_AREA);
		if (cityAreaBoMap == null) {
			Map<Integer, CityArea> cityAreaMap = cityAreaService
					.findAllCityAreaMap();
			if (cityAreaMap != null && cityAreaMap.size() > 0) {
				cityAreaBoMap = new HashMap<Integer, CityAreaBo>(
						cityAreaMap.size());
				CityAreaBo bo;
				for (Entry<Integer, CityArea> entry : cityAreaMap.entrySet()) {
					bo = new CityAreaBo();
					try {
						BeanUtils.copyProperties(bo, entry.getValue());
					} catch (Exception e) { // ignore
						continue;
					}
					cityAreaBoMap.put(entry.getKey(), bo);
					for (CityAreaBo o : cityAreaBoMap.values()) {
						if (o.getLevel().intValue() > 1
								&& cityAreaBoMap.containsKey(o.getParentId())) {
							cityAreaBoMap.get(o.getParentId())
									.addChildCityArea(o);
						}
					}
				}
			} else {
				cityAreaBoMap = Collections.emptyMap();
			}
			CacheManage.put(CITY_AREA_LIST_KEY, cityAreaBoMap,
					CacheTypeEnum.CITY_AREA);
		}
		return cityAreaBoMap;
	}

	@Autowired
	private CityAreaService cityAreaService;

}
